home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2002 November / SGI Freeware 2002 November - Disc 3.iso / dist / fw_netpbm.idb / usr / freeware / bin / ppmshadow.z / ppmshadow
Text File  |  2002-07-08  |  7KB  |  196 lines

  1. #!/bin/perl
  2. #  Change the path name in the line above to wherever Perl lives
  3. #  on your system.  This script was tested with Perl 4.0, patch
  4. #  level 36.
  5.  
  6. #                         P P M S H A D O W
  7.  
  8. #            by John Walker  --  http://www.fourmilab.ch/
  9.                            $version = 1.2;
  10. #   --> with minor changes by Bryan Henderson.  See above web site for
  11. #   the real John Walker work, named pnmshadow.
  12.  
  13. #   Pnmshadow is a brutal sledgehammer implemented in Perl which
  14. #   adds attractive shadows to images, as often seen in titles
  15. #   of World-Wide Web pages.  This program does not actually
  16. #   *do* any image processing--it simply invokes components of
  17. #   Jef Poskanzer's PBMplus package (which must be present on
  18. #   the path when this script is run) to bludgeon the source
  19. #   image into a plausible result.
  20. #
  21. #               This program is in the public domain.
  22. #
  23. #
  24.  
  25.     $fname = "/tmp/_PPMshadow$$";          # Temporary filepath prefix
  26.  
  27.     #   Process command line options
  28.  
  29.     $convolve = 11;                   # Default blur convolution kernel size
  30.     $purge = 1;                       # Set to 0 to preserve intermediate files
  31.     $translucent = 0;                 # Default not translucent
  32.  
  33.     while (@ARGV) {
  34.         $arg = shift;
  35.         if ((substr($arg, 0, 1) eq '-') && (length($arg) > 1)) {
  36.             $opt = substr($arg, 1, 1);
  37.             $opt =~ tr/A-Z/a-z/;
  38.             if ($opt eq 'b') {        # -B n  --  Blur size
  39.                 if (!defined($convolve = shift)) {
  40.                     die("Argument missing after -b option\n");
  41.                 }
  42.                 if (($convolve < 11) && (($convolve & 1) == 0)) {
  43.                     $convolve++;      # Round up even kernel specification
  44.                 }
  45.             } elsif ($opt eq 'k') {   # -K  --  Keep temporary files
  46.                 $purge = 0;
  47.             } elsif ($opt eq 't') {   # -T  --  Translucent image
  48.                 $translucent = 1;
  49.             } elsif ($opt eq 'u' || $opt eq '?') {
  50.                 print(STDERR "ppmshadow  --  Add simulated shadow to anymap.\n");
  51.                 if (defined $version) {
  52.                     print(STDERR "               Version $version.\n"); 
  53.                 }
  54.                 print(STDERR "Usage: ppmshadow [options] [pnmfile] \n");
  55.                 print(STDERR "Options:\n");
  56.                 print(STDERR "    -B n       Set blur size to n pixels\n");
  57.                 print(STDERR "    -K         Keep intermediate temporary files from run\n");
  58.                 print(STDERR "    -T         Cast shadows of translucent objects\n");
  59.                 print(STDERR "    -U         Print this message\n");
  60.                 print(STDERR "    -X n       Shift shadow n pixels to the right\n");
  61.                 print(STDERR "    -Y n       Shift shadow n pixels down\n");
  62.                 exit(0);
  63.             } elsif ($opt eq 'x') {   # -X n  --  X offset
  64.                 if (!defined($xoffset = shift)) {
  65.                     die("Argument missing after -x option\n");
  66.                 }
  67.                 if ($xoffset < 0) {
  68.                     $xoffset = -$xoffset;
  69.                 }
  70.             } elsif ($opt eq 'y') {   # -Y n  --  Y offset
  71.                 if (!defined($yoffset = shift)) {
  72.                     die("Argument missing after -x option\n");
  73.                 }
  74.                 if ($yoffset < 0) {
  75.                     $yoffset = -$xoffset;
  76.                 }
  77.             }
  78.         } else {
  79.             if (defined $ifile) {
  80.                 die("Duplicate input file specification.");
  81.             }
  82.             $ifile = $arg;            # Input file name
  83.         }
  84.     }
  85.  
  86.     #   Apply defaults for arguments not specified
  87.  
  88.     if (!(defined $xoffset)) {
  89.         #   Xoffset defaults to half the blur distance
  90.         $xoffset = int($convolve / 2);
  91.     }
  92.  
  93.     if (!(defined $yoffset)) {
  94.         #   Yoffset defaults to Xoffset, however specified
  95.         $yoffset = $xoffset;
  96.     }
  97.  
  98.     $stdin = 0;
  99.     if ((!(defined $ifile)) || ($ifile eq '-')) {
  100.         #   Input default to standard input
  101.         $stdin = 1;
  102.         $ifile = "$fname-0.ppm";
  103.         system("cat >$fname-0.ppm");
  104.     }
  105.  
  106.     #   Determine the size of the source image
  107.  
  108.     $a = `pnmfile $ifile`;
  109.     $a =~ m/.*\sP[BGP]M\s.*,\s*(\d*)\sby\s(\d*)/;
  110.     $xsize = $1;
  111.     $ysize = $2;
  112.  
  113.     #   Create a blank background bitmap the size of the source bitmap
  114.  
  115.     system("pnmcut 0 0 1 1 $ifile | pnmscale -xsize $xsize -ysize $ysize >$fname-5.ppm");
  116.  
  117.     #   Create positive mask file from input image
  118.  
  119.     system("pnmarith -difference $ifile $fname-5.ppm | pnminvert | ppmtopgm | pgmtopbm -thresh -value 1.0 >$fname-1.ppm");
  120.  
  121.     #   Create convolution kernel file to generate shadow
  122.  
  123.     open(OF, ">$fname-2.ppm");
  124.     $ckern = $convolve <= 11 ? $convolve : 11;
  125.     printf(OF "P2\n$ckern $ckern\n%d\n", $ckern * $ckern * 2);
  126.     $a = ($ckern * $ckern) + 1;
  127.     for ($i = 0; $i < $ckern; $i++) {
  128.         for ($j = 0; $j < $ckern; $j++) {
  129.             printf(OF "%d%s", $a, ($j < ($ckern - 1)) ? " " : "\n");
  130.         }
  131.     }
  132.     close(OF);
  133.  
  134.     if ($translucent) {
  135.  
  136.         #   Convolve the input colour image with the kernel
  137.         #   to create a translucent shadow image.
  138.  
  139.         system("pnmconvol $fname-2.ppm $ifile >$fname-10.ppm");
  140.         system("rm $fname-2.ppm") if $purge;
  141.         while ($ckern < $convolve) {
  142.             system("pnmsmooth $fname-10.ppm >$fname-10a.ppm");
  143.             system("mv $fname-10a.ppm $fname-10.ppm");
  144.             $ckern++;
  145.         }
  146.     } else {
  147.  
  148.         #   Convolve the positive mask with the kernel to create shadow
  149.  
  150.         system("pnmconvol $fname-2.ppm $fname-1.ppm >$fname-3.ppm");
  151.         system("rm $fname-2.ppm") if $purge;
  152.         while ($ckern < $convolve) {
  153.             system("pnmsmooth $fname-3.ppm >$fname-3a.ppm");
  154.             system("mv $fname-3a.ppm $fname-3.ppm");
  155.             $ckern++;
  156.         }
  157.  
  158.         #   Multiply the shadow by the background colour
  159.  
  160.         system("pnmarith -multiply $fname-3.ppm $fname-5.ppm >$fname-10.ppm");
  161.         system("rm $fname-3.ppm") if $purge;
  162.     }
  163.  
  164.     #   Cut an offset rectangle from the shadow image
  165.  
  166.     $i = $xsize - $xoffset;
  167.     $j = $ysize - $yoffset;
  168.     system("pnmcut 0 0 $i $j $fname-10.ppm >$fname-4.ppm");
  169.     system("rm $fname-10.ppm") if $purge;
  170.  
  171.     #   Create offset shadow image
  172.  
  173.     system("pnmpaste -replace $fname-4.ppm $xoffset $yoffset $fname-5.ppm >$fname-6.ppm");
  174.     system("rm $fname-4.ppm $fname-5.ppm") if $purge;
  175.  
  176.     #   Create inverse mask
  177.  
  178.     system("pnminvert $fname-1.ppm >$fname-7.ppm");
  179.  
  180.     #   Multiply original image by inverse mask
  181.  
  182.     system("pnmarith -multiply $ifile $fname-7.ppm >$fname-8.ppm");
  183.     system("rm $fname-7.ppm") if $purge;
  184.     system("rm $fname-0.ppm") if ($purge && $stdin);
  185.  
  186.     #   Multiply shadow by mask
  187.  
  188.     system("pnmarith -multiply $fname-6.ppm $fname-1.ppm >$fname-9.ppm");
  189.     system("rm $fname-6.ppm $fname-1.ppm") if $purge;
  190.  
  191.     #   Add masked image and shadow to obtain result, which this
  192.     #   last call on pnmarith sends to standard output.
  193.  
  194.     system("pnmarith -add $fname-8.ppm $fname-9.ppm");
  195.     system("rm $fname-8.ppm $fname-9.ppm") if $purge;
  196.